package com.imageim.yimirror.ui.activity;

import android.animation.AnimatorSet;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Rect;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.DecelerateInterpolator;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.imageim.yimirror.R;
import com.imageim.yimirror.base.BaseActivity;
import com.imageim.yimirror.base.BaseApplication;
import com.imageim.yimirror.base.Constants;
import com.imageim.yimirror.bean.analysisPhoto.AnalysisPhotoResultBean;
import com.imageim.yimirror.bean.analysisPhoto.PhotoNoBean;
import com.imageim.yimirror.common.EnviromentConfig;
import com.imageim.yimirror.common.data.CommonData;
import com.imageim.yimirror.common.event.EventCode;
import com.imageim.yimirror.common.event.EventMessage;
import com.imageim.yimirror.common.network.NetUtil;
import com.imageim.yimirror.common.network.ThreadPoolManager;
import com.imageim.yimirror.common.network.constants.NetConstants;
import com.imageim.yimirror.common.network.listener.NetCallback;
import com.imageim.yimirror.common.network.tool.ParamCreator;
import com.imageim.yimirror.common.ui.CircleAvatarView;
import com.imageim.yimirror.common.ui.SceneManager;
import com.imageim.yimirror.common.ui.analysis.AnalysisPhotoView2;
import com.imageim.yimirror.common.ui.btn.BtnCircleClose;
import com.imageim.yimirror.common.ui.dialog.PromptDialog;
import com.imageim.yimirror.common.ui.drawbody.BodyRectView;
import com.imageim.yimirror.common.ui.face.DrawFaceView;
import com.imageim.yimirror.common.ui.tip.TipUtil;
import com.imageim.yimirror.common.util.AnimUtil;
import com.imageim.yimirror.common.util.AppUtil;
import com.imageim.yimirror.common.util.CacheUtils;
import com.imageim.yimirror.common.util.FaceDetectManager;
import com.imageim.yimirror.common.util.PictureUtils;
import com.imageim.yimirror.common.util.SoundUtil;
import com.imageim.yimirror.common.util.UserUtil;
import com.imageim.yimirror.service.statistic.StatisticSDK;
import com.imageim.yimirror.ui.widght.RedPacketView;
import com.martin.ads.omoshiroilib.camera.CameraEngine;
import com.martin.ads.omoshiroilib.encoder.MediaCodecUtils;
import com.martin.ads.omoshiroilib.filter.helper.FilterType;
import com.martin.ads.omoshiroilib.flyu.fake.Logger;
import com.martin.ads.omoshiroilib.flyu.fake.LoggerFactory;
import com.martin.ads.omoshiroilib.flyu.hardcode.DemoConstants;
import com.martin.ads.omoshiroilib.flyu.hardcode.HardCodeData;
import com.martin.ads.omoshiroilib.flyu.hardcode.HardCodeHelper;
import com.martin.ads.omoshiroilib.flyu.openglfilter.common.FilterConstants;
import com.martin.ads.omoshiroilib.flyu.openglfilter.detector.DirectionDetector;
import com.martin.ads.omoshiroilib.flyu.openglfilter.gpuimage.base.FilterFactory;
import com.martin.ads.omoshiroilib.flyu.openglfilter.gpuimage.base.GPUImageFilter;
import com.martin.ads.omoshiroilib.flyu.openglfilter.gpuimage.base.GPUImageFilterGroupBase;
import com.martin.ads.omoshiroilib.flyu.openglfilter.gpuimage.changeface.ChangeFaceInfo;
import com.martin.ads.omoshiroilib.flyu.openglfilter.gpuimage.changeface.ChangeFaceNet;
import com.martin.ads.omoshiroilib.flyu.openglfilter.gpuimage.dstickers.DynamicStickerData;
import com.martin.ads.omoshiroilib.flyu.openglfilter.gpuimage.dstickers.DynamicStickerMulti;
import com.martin.ads.omoshiroilib.flyu.openglfilter.gpuimage.filtergroup.GPUImageFilterGroup;
import com.martin.ads.omoshiroilib.flyu.openglfilter.gpuimage.filtergroup.GPUImageMultiSectionGroup;
import com.martin.ads.omoshiroilib.flyu.openglfilter.gpuimage.filtergroup.MultiSectionInfo;
import com.martin.ads.omoshiroilib.flyu.openglfilter.gpuimage.multitriangle.DrawMultiTriangleNet;
import com.martin.ads.omoshiroilib.flyu.openglfilter.gpuimage.multitriangle.MultiTriangleInfo;
import com.martin.ads.omoshiroilib.flyu.openglfilter.gpuimage.switchface.CloneFaceFilter;
import com.martin.ads.omoshiroilib.flyu.openglfilter.gpuimage.switchface.SwitchFaceInfo;
import com.martin.ads.omoshiroilib.flyu.openglfilter.gpuimage.switchface.SwitchFaceNet;
import com.martin.ads.omoshiroilib.flyu.openglfilter.gpuimage.switchface.TwoPeopleSwitch;
import com.martin.ads.omoshiroilib.flyu.sdk.mediaplayer.AudioFocusCore;
import com.martin.ads.omoshiroilib.glessential.CameraView;
import com.martin.ads.omoshiroilib.glessential.GLRootView;
import com.martin.ads.omoshiroilib.ui.face.FaceWrapper;
import com.martin.ads.omoshiroilib.util.BitmapUtils;
import com.martin.ads.omoshiroilib.util.FileUtils;
import com.nineoldandroids.animation.Animator;
import com.nineoldandroids.animation.AnimatorListenerAdapter;
import com.nineoldandroids.animation.ObjectAnimator;
import com.sensetime.stmobileapi.STMobile106;
import com.tencent.bugly.beta.Beta;

import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;

import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Random;

import butterknife.BindView;
import butterknife.ButterKnife;

/**
 * Created by Bruce.Zhou on 2018/7/5 12:52.
 * Email: 907160968@qq.com
 */
public class ScanFaceActivity extends BaseActivity implements GPUImageFilterGroupBase.IGroupStateChanged,
        FaceWrapper.FaceDetectResultListener {
    private final static Logger log = LoggerFactory.getLogger();
    @BindView(R.id.camera_view)
    GLRootView mCameraView;
    @BindView(R.id.tv_frag_camera_time_lapse_number)
    TextView mTvFragCameraTimeLapseNumber;
    @BindView(R.id.tv_version)
    TextView mTvVersion;
    @BindView(R.id.iv_anim_camera)
    ImageView mIvAnimCamera;
    @BindView(R.id.red_packet_view)
    RedPacketView mRedPacketView;
    @BindView(R.id.btn_close)
    BtnCircleClose mBtnClose;
    @BindView(R.id.tv_tip_msg)
    TextView mTvTipMsg;
    @BindView(R.id.panel_tip_stand_position)
    LinearLayout mPanelTipStandPosition;
    @BindView(R.id.iv_back)
    ImageView mIvBack;
    @BindView(R.id.iv_next)
    ImageView mIvNext;
    @BindView(R.id.iv_camera)
    ImageView mIvCamera;
    @BindView(R.id.ca_view)
    CircleAvatarView mCaView;
    @BindView(R.id.panel_bottom)
    RelativeLayout mPanelBottom;
    @BindView(R.id.tv_time_count)
    TextView mTvTimeCount;
    @BindView(R.id.iv_foot)
    ImageView mIvFoot;
    @BindView(R.id.tv_tip_stand)
    TextView mTvTipStand;
    @BindView(R.id.iv_loading)
    ImageView mIvLoading;
    @BindView(R.id.ll_loading)
    LinearLayout mLlLoading;
    @BindView(R.id.root)
    RelativeLayout mRoot;
    private CameraView cameraView;
    private int surfaceWidth, surfaceHeight;
    private boolean canUseMediaCodec;
    private GLRootView glRootView;
    private DrawFaceView mDrawFaceView;
    private BodyRectView bodyRectView;
    private Handler mHander;
    private boolean isTakingPic;
    private static final int MSG_TAKE_PIC = 100;
    private static final int MSG_GET_ANALYSIS_RESULT = 101;
    private static final int MSG_TAKE_PIC_NEW = 102;
    private static final int MSG_RESTART_BTN_CLOSE = 103;
    private boolean isFaceInValidArea;
    private View ivCamera;
    private int timeCount = 5;
    private boolean stopFaceDetect;
    private boolean isUploading;
    private Bitmap photoBitmap;
    private Bitmap clipedBitmap;
    private Bitmap faceBitmap;
    private AnalysisPhotoView2 analysisPhotoView;
    private String photoNo;
    private int analysisCount = 0;
    private static final double preferedRatio = 4.0 / 3;
    private PromptDialog mPromptDialog;
    private ViewGroup panelTipStandPosition;
    private int closeTime = 60;
    private String mFaceStr;
    private int mRedPacketSupport;
    private int mRedPacketNumFlag;
    private Bitmap bitmap;


    public static class Myhandler extends Handler {

        private WeakReference<ScanFaceActivity> reference;

        public Myhandler(ScanFaceActivity activity) {
            reference = new WeakReference<>(activity);
        }

        @Override
        public void handleMessage(Message msg) {
            final ScanFaceActivity activity = reference.get();
            if (activity != null) {
                switch (msg.what) {
                    case MSG_TAKE_PIC_NEW:
                        if (activity.isTakingPic && activity.isFaceInValidArea) {
                            activity.bodyRectView.resetBtnTimer();
                        }
                        activity.resetCloseTime();
                        break;
                    case MSG_TAKE_PIC:
                        if (!activity.isFaceInValidArea) {
                            activity.hideTimeCount();
                            return;
                        }
                        activity.mTvTimeCount.setVisibility(View.VISIBLE);
                        Animation scale = AnimationUtils.loadAnimation(BaseApplication.getContext(), R.anim.anim_scan_pic_time_scale);
                        scale.setAnimationListener(new Animation.AnimationListener() {
                            @Override
                            public void onAnimationStart(Animation animation) {
                            }

                            @Override
                            public void onAnimationEnd(Animation animation) {
                                activity.mTvTimeCount.setVisibility(View.INVISIBLE);
                            }

                            @Override
                            public void onAnimationRepeat(Animation animation) {
                            }
                        });
                        scale.setStartOffset(200);
                        activity.mTvTimeCount.startAnimation(scale);
                        // 倒计时
                        activity.mTvTimeCount.setText(String.valueOf(activity.timeCount));
                        activity.timeCount--;
                        if (activity.timeCount == 0) {
                            if (activity.isFaceInValidArea) {
                                activity.takePic();
                            } else {
                                activity.hideTimeCount();
                            }
                        } else {
                            Message nextMsg = Message.obtain();
                            nextMsg.what = MSG_TAKE_PIC;
                            activity.mHander.removeMessages(MSG_TAKE_PIC);
                            activity.mHander.sendMessageDelayed(nextMsg, 1000);
                        }
                        break;
                    case MSG_GET_ANALYSIS_RESULT:
                        activity.mHander.removeMessages(MSG_GET_ANALYSIS_RESULT);
                        if (activity.analysisCount < 31) {
                            activity.getAnalysisResult();
                            activity.analysisCount++;
                        } else {
                            postDelayed(() -> activity.finish(), 3500);
                            activity.showTipStand("哎呀，识别错误了，请重新拍照尝试~");
                            activity.hideLoadingArea();
                        }
                        break;
                    case MSG_RESTART_BTN_CLOSE:
                        activity.mHander.removeMessages(MSG_RESTART_BTN_CLOSE);
                        activity.mBtnClose.restart(activity.closeTime);
                        break;
                    default:
                }
            }
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        AppUtil.setLight(this, 255);
        super.onCreate(savedInstanceState);
        timeCount = 5;
        init();
        mHander = new Myhandler(this);
    } // onCreate

    private void hideTimeCount() {
        timeCount = 5;
        mTvTimeCount.setVisibility(View.GONE);
        isTakingPic = false;
    }


    private void init() {
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        //        WindowManager.LayoutParams params = getWindow().getAttributes();
        //        params.flags |= WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
        //        getWindow().setAttributes(params);
        //        TipUtil.toast("screenWidth=" +screenWidth + ",screenheight=" + screenHeight);
        glRootView = findViewById(R.id.camera_view);
        cameraView = new CameraView(this, glRootView, preferedRatio);
        cameraView.setScreenSizeChangedListener(new CameraView.ScreenSizeChangedListener() {
            @Override
            public void updateScreenSize(int width, int height) {
                surfaceWidth = width;
                surfaceHeight = height;
            }
        });

        mDrawFaceView = new DrawFaceView(this);
        int cHeight;
        int cWidth;
        if (EnviromentConfig.IS_LANDSCAPE) {
            cHeight = screenHeight;
            cWidth = (int) (screenHeight * (1 / CameraEngine.preferredRatio));
        } else {
            cWidth = screenWidth;
            cHeight = (int) (screenWidth * CameraEngine.preferredRatio);
        }
        RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(cWidth, cHeight);
        lp.addRule(RelativeLayout.CENTER_IN_PARENT);
        mDrawFaceView.setLayoutParams(lp);
        RelativeLayout root = findViewById(R.id.root);
        root.addView(mDrawFaceView, 1);
        // Add body rect view
        bodyRectView = new BodyRectView(this);
        bodyRectView.setOnTimeCountOverListener(new BodyRectView.OnTimeCountOverListener() {
            @Override
            public void onTimeOver() {
                stopFaceDetect = true;
                SoundUtil.playAsyc(mContext, R.raw.shutter, false);
                takePic();
                bodyRectView.hideBtnTimerAnim();
            }
        });
        bodyRectView.setLayoutParams(lp);
        root.addView(bodyRectView, 2);

        canUseMediaCodec = MediaCodecUtils.checkMediaCodecVideoEncoderSupport() == MediaCodecUtils.CODEC_SUPPORTED
                &&
                MediaCodecUtils.checkMediaCodecAudioEncoderSupport() == MediaCodecUtils.CODEC_SUPPORTED;
        HardCodeHelper.decompressAllResource(this);
        initUIandEvent();
        cameraView.getGlRender().switchLastFilterOfCustomizedFilters(FilterType.BEAUTIFY_A);
        // initCovers();
        mTvVersion.setText(AppUtil.getVersionName(mContext));
        showCameraAnim();
    }


    @Override
    public void onEventMainThread(EventMessage event) {
        super.onEventMainThread(event);
        switch (event.getCode()) {
            case EventCode.CODE_FINISH:
                finish();
                break;
            case EventCode.CODE_HIDE_CAMERA_ANIM:
                AnimUtil.scaleToDismiss(ivCamera);
                break;
            default:
        }
    }

    private void takePic() {
        showLoading();
        cameraView.getGlRender().addRunnableOnDrawEnd(new Runnable() {
            @Override
            public void run() {
                BitmapUtils.sendImage(
                        surfaceWidth,
                        surfaceHeight,
                        mContext,
                        new FileUtils.FileSavedCallback() {
                            @Override
                            public void onFileSaved(final String filePath) {
                                hideTimeCount();
                                stopFaceDetect = true;
                                isTakingPic = false;
                                new DealPhotoTask(filePath).executeOnExecutor(ThreadPoolManager.getInstance().getThreadPool());
                                // 释放相机，并显示分析视图
                                //                                releaseCamera();
                                //                                showAnalysisPhotoView(filePath);
                                //                                btnClose.setVisibility(View.INVISIBLE);
                                mTvVersion.setVisibility(View.GONE);
                                //                                // 上传用户照片，获取唯一的photoId
                                //                                uploadUserPhoto();
                            }
                        }
                );
            }
        });
    }

    String clipBitmap;

    private class DealPhotoTask extends AsyncTask<Void, Void, String> {
        private String filePath;

        public DealPhotoTask(String filePath) {
            this.filePath = filePath;
        }

        @Override
        protected String doInBackground(Void... voids) {
            mFaceStr = null;
            photoBitmap = PictureUtils.getImage(filePath);
            //            faceBitmap = FaceDetectManager.getInstance().getBigestFace(photoBitmap);
            // 裁剪后的bitmap
            clipedBitmap = FaceDetectManager.getInstance().clipBody(photoBitmap);
            //保存
            if (clipedBitmap != null) {
                clipBitmap = BitmapUtils.bitmapToBase64(clipedBitmap, 100);
                UserUtil.setClipBitmap(clipBitmap);
            }

            if (!CommonData.isFullBody || CommonData.faceBitmap == null) {
                runOnUiThread(() -> {
                    showTipStand("^ o请拍一张全身照好吗^_^");
                    hideTimeCount();
                });
            } else {
                if (CommonData.faceBitmap != null) {
                    faceBitmap = CommonData.faceBitmap;
                    mFaceStr = BitmapUtils.bitmapToBase64(faceBitmap, 100);
                    CacheUtils.setString(mContext, Constants.FACE_STR, mFaceStr);
                    CommonData.faceBitmap = null;
                    faceBitmap.recycle();

                    uploadUserPhoto();

                }
            }
            return mFaceStr;
        }

        @Override
        protected void onPostExecute(String faceStr) {
            hideLoading();
            if (clipedBitmap != null) {
                //                showAnalysisPhotoView(clipedBitmap);
            } else {
                if (!CommonData.isFullBody) {
                    stopFaceDetect = false;
                    hideTimeCount();
                    return;
                }
            }
            if (faceStr == null) {
                stopFaceDetect = false;
                hideTimeCount();
                //                reShowTakePicBtn();
                showTipStand("^ o识别失败，请调整您站立的位置^_^");
            } else {
                bodyRectView.stopScanAnim();
                //                releaseCamera();
                //                stopQuitTimer();
                //                analysisPhotoView.setAvatar();
            }
        }
    } // DealPhotoTask

    @Override
    protected void onPause() {
        super.onPause();
        if (cameraView != null) {
            cameraView.onPause();
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (cameraView != null) {
            cameraView.onResume();
        }
        isTakingPic = false;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        releaseCamera();
        mContext = null;
        if (mHander != null) {
            mHander.removeCallbacksAndMessages(null);
        }
        if (photoBitmap != null && !photoBitmap.isRecycled()) {
            photoBitmap.recycle();
        }

        if (bitmap != null && !bitmap.isRecycled()) {
            bitmap.recycle();
        }

    }


    private void releaseCamera() {
        mDrawFaceView.stopDraw();
        if (cameraView != null) {
            cameraView.onDestroy();
        }
        if (glRootView != null) {
            glRootView.destroyDrawingCache();
        }
        deInitUIandEvent();
    }

    @Override
    protected void initBundle() {
    }

    @Override
    protected int getLayoutId() {
        return R.layout.camera_preview;
    }


    @Override
    protected void initView() {
        ButterKnife.bind(this);
        Glide.with(this)
                .load(R.drawable.ic_loading)
                .asGif()
                .diskCacheStrategy(DiskCacheStrategy.NONE)
                .into(mIvLoading);
        //        mTvTimeCount.setVisibility(View.GONE);
        mPanelTipStandPosition.setVisibility(View.GONE);
        mIvFoot.setVisibility(View.GONE);
        mTvTipStand.setVisibility(View.GONE);

        bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_fireworks);

    }

    @Override
    protected void initListener() {
        super.initListener();
        mBtnClose.setCloseImage(0, closeTime);
        mBtnClose.setOnTimeOverListener(new BtnCircleClose.OnTimeOverListener() {
            @Override
            public void onTimeOver() {
                finish();
            }
        });

        mRedPacketView.getRedPacketView().setOnRedPacketClickListener((redPacket, oldY) -> {
            final ImageView iv = new ImageView(this);
            mRoot.addView(iv);
            iv.setImageBitmap(bitmap);
            iv.setX(redPacket.x);
            iv.setY(oldY);
            AnimatorSet set = new AnimatorSet();
            android.animation.ObjectAnimator scaleY = android.animation.ObjectAnimator.ofFloat(iv, "scaleY", 0, 1.2f);
            android.animation.ObjectAnimator scaleX = android.animation.ObjectAnimator.ofFloat(iv, "scaleX", 0, 1.2f);
            set.playTogether(scaleX, scaleY);
            set.setInterpolator(new DecelerateInterpolator());
            set.setDuration(500);
            set.start();

            set.addListener(new android.animation.AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(android.animation.Animator animation) {
                    mRoot.removeView(iv);
                }
            });
        });
    }

    private void showTipStand(String msg) {
        mTvTipMsg.setText(msg);
        ObjectAnimator moveIn = ObjectAnimator.ofFloat(mPanelTipStandPosition, "translationY", -300, 0);
        moveIn.setDuration(1000);
        moveIn.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                mPanelTipStandPosition.postDelayed(() -> hideTipStand(), 2400);
            }
        });
        moveIn.start();
        mPanelTipStandPosition.setVisibility(View.VISIBLE);
    }

    private void hideTipStand() {
        mPanelTipStandPosition.setVisibility(View.VISIBLE);
        ObjectAnimator moveIn = ObjectAnimator.ofFloat(mPanelTipStandPosition, "translationY", 0, -300);
        moveIn.setDuration(800);
        moveIn.start();
    }

    private String photoStr = null;

    private void uploadUserPhoto() {
        if (!isUploading && photoBitmap != null) {
            isUploading = true;
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    showLoading();
                    showLoadingArea();
                }
            });
            new AsyncTask<Void, Void, String>() {
                @Override
                protected void onPreExecute() {
                }

                @Override
                protected String doInBackground(Void... voids) {
                    if (photoBitmap != null && photoStr == null) {
                        photoStr = BitmapUtils.bitmapToBase64(photoBitmap, 93);
                        photoBitmap.recycle();
                    }
                    //                    logD("time used : " + (System.currentTimeMillis() - startTime));
                    upload(photoStr);
                    //                    return photoStr;
                    return null;
                }

                @Override
                protected void onPostExecute(String photoStr) {
                    //                    upload(photoStr);
                }
            }.executeOnExecutor(ThreadPoolManager.getInstance().getThreadPool());
        }
    }

    private void upload(final String photoStr) {
        List<BasicNameValuePair> params = new ParamCreator()
                .add("userPhoto", photoStr)
                .add("clipedBitmap", clipBitmap)
                .build();
        NetUtil.postObject(mContext, NetConstants.URL.UPLOAD_SCAN_PHOTO, params, new NetCallback<PhotoNoBean>() {
            @Override
            public void onStart() {
                mHander.sendEmptyMessage(MSG_RESTART_BTN_CLOSE);
            }

            @Override
            public void onSuccess(PhotoNoBean result) {
                cancelCloseTime();
                hideLoading();
                //                String s = JsonUtil.gson.toJson(result);
                //                LogUtil.d("data", "photoNo : " + JsonUtil.gson.toJson(result));
                // 显示bodyline
                if (result != null) {
                    UserUtil.setBeanByGson(Constants.BODY_LINE_PARAM, result);
                }

                //                analysisPhotoView.setBodyData(result);
                photoNo = result.getPhotoNo();
                mHander.sendEmptyMessageDelayed(MSG_GET_ANALYSIS_RESULT, 1000);
                UserUtil.setPhotoNo(photoNo);
                isUploading = false;
            }

            @Override
            public void onFail(int errorCode, String errorMsg) {
                hideLoading();
                TipUtil.show(errorCode + errorMsg);
                isUploading = false;
                finish();
                //                analysisPhotoView.showPanelBodyLine(false);
            }
        }, PhotoNoBean.class);
    } // upload

    /**
     * 获取照片分析结果
     */
    private void getAnalysisResult() {
        List<BasicNameValuePair> params = new ParamCreator().add("photoNo", photoNo).build();
        NetUtil.getObject(mContext, NetConstants.URL.GET_ANALYSIS_PHOTO_RESULT, params, new NetCallback<AnalysisPhotoResultBean>() {
            @Override
            public void onStart() {
                mHander.sendEmptyMessage(MSG_RESTART_BTN_CLOSE);
            }

            @Override
            public void onSuccess(AnalysisPhotoResultBean result) {
                int gender = result.getGender();
                UserUtil.setGender(gender);

                // 必须移到此位置，以便能在ifAll!=2时进入到这个流程
                if (result.getIfAll() != 2 && result.getIfAll() != 3) {
                    if (mHander != null) {
                        mHander.sendEmptyMessageDelayed(MSG_GET_ANALYSIS_RESULT, 400);
                    }
                }

                if (result.getIfAll() == 1 || result.getIfAll() == 2) { // 正在分析或正确分析完成
                    //                    analysisPhotoView.setAnalysisData(result);
                    // 判断人脸风格是否完成分析
                    if (!TextUtils.isEmpty(result.getFaceStyleName()) && analysisCount >= 22 && analysisCount < 30) {
                        UserUtil.setUserId(result.getUserId());
                        //                        SceneManager.toScene(mContext, MainActivity.class, null);
                        //                        finish();
                        return;
                    }
                    //----------------------------------
                    if (result.getIfAll() == 2) {
                        //分析完成
                        UserUtil.setUserId(result.getUserId());
                        //红包二维码和金额
                        UserUtil.setRedPacketQrCode(result.getRedPacketScanQrcode());
                        UserUtil.setRedPacketAmount(result.getRedPacketAmount());

                        if (!TextUtils.isEmpty(result.getFaceStyleName()) && result.getFaceStyleId() != 0) {
                            int faceStyleId = result.getFaceStyleId();
                            UserUtil.setStyleId(faceStyleId);
                            //用户是否是当天第一次进入APP 0未进入  1进入过
                            int todayHasUse = result.getTodayHasUse();
                            UserUtil.setTodayHasUse(todayHasUse);
                        }

                        // 隐藏进度条
                        hideLoadingArea();

                        //根据店铺是否支持红包以及余额设置
                        if (mRedPacketSupport == Constants.SUPPORT_RED_PACKET) {
                            //红包仍有余额  判断是否领取过
                            int redPacketNumFlag = result.getRedPacketNumFlag();
                            if (redPacketNumFlag == Constants.RED_PACKET_NOT_EMPTY) {
                                //是否已经领取过  1 今日已领取  2.今日未领取
                                int receiveRedPacketFlag = result.getReceiveRedPacketFlag();
                                //                                UserUtil.setReceiveRedPacketFlag(receiveRedPacketFlag);
                                releaseCamera();
                                if (receiveRedPacketFlag == 1) {
                                    mRedPacketView.showTitle(RedPacketView.RED_PACKET_YET_GET);
                                    goToNextActivity();
                                } else {
                                    //开始红包雨倒计时
                                    mRedPacketView.showStartTitle();
                                }

                            } else {
                                mRedPacketView.showTitle(RedPacketView.RED_PACKET_ALL_EMPTY);
                                goToNextActivity();
                            }

                        } else {
                            goToNextActivity();
                        }

                    }
                } else if (result.getIfAll() == 3) { // 无法分析
                    //隐藏进度条
                    hideLoadingArea();
                }
                //
            }

            @Override
            public void onFail(int errorCode, String errorMsg) {
                if (errorCode == 1000) {
                    if (mHander != null) {
                        mHander.sendEmptyMessageDelayed(MSG_GET_ANALYSIS_RESULT, 400);
                    }
                } else {
                    toast(errorMsg + errorCode);
                }
                hideLoadingArea();
            }
        }, AnalysisPhotoResultBean.class);
    }


    private void goToNextActivity() {
        mHander.postDelayed(new Runnable() {
            @Override
            public void run() {
                SceneManager.toScene(mContext, BodyAndRadarActivity.class, null);
                overridePendingTransition(R.anim.scale_in, 0);
                finish();
            }
        }, 1000);

    }


    private void showCameraAnim() {
        ivCamera = findViewById(R.id.iv_anim_camera);
        AnimUtil.scaleUp(ivCamera);
        ivCamera.postDelayed(new Runnable() {
            @Override
            public void run() {
                mIvFoot.setVisibility(View.VISIBLE);
                mTvTipStand.setVisibility(View.VISIBLE);
                SoundUtil.playAsyc(mContext, R.raw.before_takepic_bg, false);


                //TODO 根据店铺配置设置是否显示春节活动
                mRedPacketSupport = UserUtil.getRedPacketSupport();
                if (mRedPacketSupport == Constants.SUPPORT_RED_PACKET) {
                    mRedPacketNumFlag = UserUtil.getRedPacketNumFlag();
                    if (mRedPacketNumFlag == Constants.RED_PACKET_NOT_EMPTY) {
                        //红包还有余额
                        mRedPacketView.showTitle(RedPacketView.RED_PACKET_BEFORE);
                    } else {
                        //红包已经领完
                        mRedPacketView.showTitle(RedPacketView.RED_PACKET_ALL_EMPTY);
                    }
                    mRedPacketView.setVisibility(View.VISIBLE);

                    StatisticSDK.onEvent(103);
                }
            }
        }, 4800);
    }

    @Override
    protected void initData() {
        playSound();
    }

    private void playSound() {
        int index = new Random().nextInt(3);
        switch (index) {
            case 0:
                SoundUtil.play(R.raw.a001);
                break;
            case 1:
                SoundUtil.play(R.raw.a002);
                break;
            case 2:
                SoundUtil.play(R.raw.a003);
                break;
            default:
        }
    }


    @Override
    public void onFaceInfoList(final STMobile106[] faceInfoList) {
        if (stopFaceDetect) {
            return;
        }
        if (faceInfoList != null && faceInfoList.length > 0) {
            STMobile106 maxFace = null; // 最大的并且在有效画面区域的人脸
            if (faceInfoList.length > 1) {
                List<STMobile106> faceList = Arrays.asList(faceInfoList);
                faceList.sort(faceSizeComparator);
                for (int i = 0; i < faceList.size(); i++) {
                    if (isFaceInValidArea(faceList.get(i))) {
                        maxFace = faceList.get(i);
                        break;
                    }
                }
                if (maxFace == null) {
                    maxFace = faceList.get(0);
                }
            } else {
                maxFace = faceInfoList[0];
            }
            isFaceInValidArea = (maxFace != null);
            if (maxFace != null) {
                Rect faceRect = maxFace.getRect();
                int left = (int) (bodyRectView.getWidth() - faceRect.left * CameraEngine.transRate - faceRect.width() * 2 + faceRect.width() / 4.4f);
                int top = (int) (bodyRectView.getHeight() - faceRect.top * CameraEngine.transRate - faceRect.height() * 2);

                if (!isTakingPic && left > (bodyRectView.getWidth() - 600) / 2f && left < (bodyRectView.getWidth() + 600) / 2f) {
                    //检测到人脸  取消倒计时关闭页面
                    isTakingPic = true;
                    Message msg = new Message();
                    msg.what = MSG_TAKE_PIC_NEW;
                    mHander.removeMessages(MSG_TAKE_PIC_NEW);
                    mHander.sendMessageDelayed(msg, 1200);
                }

                if (isTakingPic && !(left > (bodyRectView.getWidth() - 600) / 2f && left < (bodyRectView.getWidth() + 600) / 2f)) {
                    //没有检测到人脸  开始倒计时关闭页面
                    hideNewTimerCount();
                }
                // face position
                //                int redPacketWidth = (faceRect.right - faceRect.left) * 2;
                //                int redPacketHeight = (faceRect.bottom - faceRect.top) * 2;
                //                float x = left + redPacketWidth / 2f;
                //                x = Math.max((bodyRectView.getWidth() - 600) / 2f, x);
                //                x = Math.min((bodyRectView.getWidth() + 600) / 2f, x);
                //                float y = top + redPacketHeight / 2f;
                //                y = Math.max((bodyRectView.getHeight() - 1188), y);
                //                bodyRectView.setLineXY(x, y);
            } else {
                //没有检测到人脸  开始倒计时关闭页面
                //                startAutoExit();
                hideNewTimerCount();
            }
        } else {
            //没有检测到人脸  开始倒计时关闭页面
            //            if (!autoExitIng) {
            //                //                startAutoExit();
            //            }
            isFaceInValidArea = false;
            hideNewTimerCount();
        }
    }

    private void hideNewTimerCount() {
        if (isTakingPic) {
            isTakingPic = false;
            mHander.removeMessages(MSG_TAKE_PIC_NEW);
            bodyRectView.hideBtnTimerAnim();
        }
    }

    public Comparator<STMobile106> faceSizeComparator = (f1, f2) -> f2.getRect().width() - f1.getRect().width();

    private static final int TRANSFORM_DX = 0;

    public boolean isFaceInValidArea(STMobile106 face) {
        //        if (EnviromentConfig.IS_LANDSCAPE) {
        //            if (TRANSFORM_DX == 0) {
        //                return false;
        //            }
        //        }

        if (face == null) {
            return false;
        }
        Rect faceRect = face.getRect();
        float left;
        //        float top;
        if (EnviromentConfig.IS_MIRROR) {
            if (EnviromentConfig.IS_LANDSCAPE) {
                left = faceRect.left * 2 - TRANSFORM_DX;
                //                top = faceRect.top * 2;
            } else {
                left = (int) (bodyRectView.getWidth() - faceRect.left * CameraEngine.transRate - faceRect.width() * 2);
                //                top = (int) (bodyRectView.getHeight() - faceRect.top * CameraEngine.transRate - faceRect.redPacketHeight() * 2);
            }
        } else {
            left = bodyRectView.getWidth() - faceRect.right * 2 + TRANSFORM_DX;
            //            top = faceRect.top * 2;
        }
        float faceWidth = faceRect.width() * 2;
        //        float faceHeight = faceRect.redPacketHeight() * 2;

        ////        Canvas canvas = holder.lockCanvas();
        //        if (canvas != null) {
        //            canvas.drawRect(new RectF(0, 0,
        //                    getWidth(), screenHeight), paint);
        //        }
        ////        holder.unlockCanvasAndPost(canvas);

        //        return (left >= 0) && (left <= bodyRectView.getWidth() - faceWidth)
        //                && (top <= bodyRectView.getHeight() - faceHeight);
        return (left >= (bodyRectView.getWidth() - 600) / 2f && (left + faceWidth / 2 <= (bodyRectView.getWidth() + 600) / 2f)); // 人脸在方框内
    }

    //    @Override
    //    public void onClick(View v) {
    //        switch (v.getId()) {
    //            case R.id.btn_close:
    //                finish();
    //                break;
    //            default:
    //        }
    //    }

    protected DirectionDetector mDirectionDetector;

    protected GPUImageFilterGroupBase mCurrentFilter;

    private int mMaxFaceCount = 5;

    private FaceWrapper faceWrapper;

    private void deinitVDM() {
        if (null != mDirectionDetector) {
            mDirectionDetector.stop();
            mDirectionDetector = null;
        }

        if (null != faceWrapper) {
            faceWrapper.uninit();
            faceWrapper = null;
        }
        mCurrentFilter = null;
    }

    private void doUpdateFilter(HardCodeData.EffectItem item) {
        GPUImageFilterGroupBase filterGroup = parseEffect(item.type, DemoConstants.APPDIR + "/" + item.unzipPath);
        filterGroup.setGroupStateChangedListener(this);
        if (null != faceWrapper) {
            mCurrentFilter = filterGroup;
            mCurrentFilter.setPhoneDirection(mDirectionDetector.getDirection());
            faceWrapper.setFilter(mCurrentFilter);
        }

        if (mMaxFaceCount > FilterConstants.MAX_FACE_COUNT) {
            mMaxFaceCount = FilterConstants.MAX_FACE_COUNT;
        }

        if (null != faceWrapper && null != faceWrapper.getGlRender()) {
            faceWrapper.getGlRender().switchDetectMaxFaceCount(mMaxFaceCount);
        }
    }

    private void doUpdateFaceDetector() {
        if (faceWrapper == null) {
            return;
        }

        if (faceWrapper.getGlRender() == null) {
            return;
        }

        faceWrapper.getGlRender().initFaceDetector();
        faceWrapper.getGlRender().switchDetectMaxFaceCount(mMaxFaceCount);
    }

    public final static int TYPE_CHANGE_FACE = 0;
    public final static int TYPE_DYNAMIC_STICKER = 1;
    public final static int TYPE_SWITCH_FACE = 2;
    public final static int TYPE_MULTI_SECTION = 3;
    public final static int TYPE_MULTI_TRIANGLE = 4;  // 注意强制更新的内容
    public final static int TYPE_TWO_PEOPLE_SWITCH = 5;
    public final static int TYPE_CLONE_PEOPLE_FACE = 6;

    protected GPUImageFilterGroupBase parseEffect(int type, String unzipPath) {
        GPUImageFilterGroupBase groupBase = new GPUImageFilterGroup();
        groupBase.addFilter(new GPUImageFilter());
        if (type < 0) {
            return groupBase;
        }
        try {
            if (type == TYPE_CHANGE_FACE) {
                ChangeFaceInfo changeFaceInfo = FilterFactory.readChangeFaceInfo(unzipPath);
                groupBase.addFilter(new ChangeFaceNet(unzipPath, changeFaceInfo));
            } else if (type == TYPE_DYNAMIC_STICKER) {
                DynamicStickerData data = FilterFactory.readDynamicStickerData(unzipPath);
                groupBase.addFilter(new DynamicStickerMulti(unzipPath, data));
            } else if (type == TYPE_SWITCH_FACE) {
                SwitchFaceInfo switchFaceInfo = FilterFactory.readSwitchFaceData(unzipPath);
                groupBase.addFilter(new SwitchFaceNet(unzipPath, switchFaceInfo));
            } else if (type == TYPE_MULTI_SECTION) {
                MultiSectionInfo multiSectionInfo = FilterFactory.readMultiSectionData(unzipPath);
                groupBase = new GPUImageMultiSectionGroup(unzipPath, multiSectionInfo);
                groupBase.addFilter(new GPUImageFilter());
            } else if (type == TYPE_MULTI_TRIANGLE) {
                MultiTriangleInfo info = FilterFactory.readMultiTriangleInfo(unzipPath);
                groupBase.addFilter(new DrawMultiTriangleNet(unzipPath, info));
            } else if (type == TYPE_TWO_PEOPLE_SWITCH) {
                groupBase.addFilter(new TwoPeopleSwitch());
            } else if (type == TYPE_CLONE_PEOPLE_FACE) {
                groupBase.addFilter(new CloneFaceFilter());
            }
        } catch (IOException e) {
            logE("read effect filter data failed, " + e.getMessage());
        } catch (JSONException e) {
            logE("parse effect filter data failed, " + e.getMessage());
        }
        return groupBase;
    }

    protected void initUIandEvent() {
        // init faceu related
        AudioFocusCore.initialize(mContext);
        mCurrentFilter = new GPUImageFilterGroup();
        mCurrentFilter.addFilter(new GPUImageFilter());
        if (null == mDirectionDetector) {
            mDirectionDetector = new DirectionDetector(this, false);
            mDirectionDetector.start();
        }
        // GPUVideoViewDecorator 是先做的翻转，再做的旋转
        faceWrapper = new FaceWrapper(this, cameraView.getGlRender());
        faceWrapper.setDirectionDetector(mDirectionDetector);
        faceWrapper.setFaceDetectResultListener(this); // face detect listener
        faceWrapper.getGlRender().setUpCamera(cameraView.getCameraEngine().getDisplayRotate(),
                cameraView.getGlRender().isCameraFacingFront(), true);

        doUpdateFilter(HardCodeData.itemList.get(0));
        doUpdateFaceDetector();
    }

    int rotateIndex = 0;
    boolean isHorizontalFilp = false;
    boolean isVerticalFilp = false;
    int currAngel = 0;

    public void rotateCamera(View v) {
        int direction = 0;
        switch (rotateIndex % 4) {
            case 0:
                currAngel = 0;
                direction = 0;
                break;
            case 1:
                currAngel = 90;
                direction = 1;
                break;
            case 2:
                currAngel = 180;
                direction = 2;
                break;
            case 3:
                currAngel = 270;
                direction = 3;
                break;
            default:
        }
        //        faceWrapper.getGlRender().setUpCamera(currAngel,
        //                isHorizontalFilp, isVerticalFilp);
        rotateIndex++;
        //        TipUtil.toast("currAngel=" + currAngel);

        faceWrapper.setFaceDirection(direction);
        toast("direction=" + direction);
    }


    public void flipHorizontal(View v) {
        isHorizontalFilp = !isHorizontalFilp;
        faceWrapper.getGlRender().setUpCamera(currAngel,
                isHorizontalFilp, isVerticalFilp);
        toast("isVerticalFilp=" + isVerticalFilp);
        toast("isHorizontalFilp=" + isHorizontalFilp);
    }

    public void flipVertical(View v) {
        isVerticalFilp = !isVerticalFilp;
        faceWrapper.getGlRender().setUpCamera(currAngel,
                isHorizontalFilp, isVerticalFilp);
        toast("isVerticalFilp=" + isVerticalFilp);
        toast("isHorizontalFilp=" + isHorizontalFilp);
    }


    protected void deInitUIandEvent() {
        deinitVDM();
    }

    @Override
    public void onTipsAndCountChanged(int maxCount, final String tips, final int duration) {
        mMaxFaceCount = maxCount;
        if (null != faceWrapper && null != faceWrapper.getGlRender()) {
            faceWrapper.getGlRender().switchDetectMaxFaceCount(mMaxFaceCount);
        }
        logD("onTipsAndCountChanged " + maxCount + " " + tips + " " + duration);
    }

    public void checkUpgrade(View v) {
        Beta.checkUpgrade(true, false);
    }

    @Override
    public boolean isSupportSwipeBack() {
        return false;
    }


    private void resetCloseTime() {
        if (mBtnClose != null && mBtnClose.getCount() <= 30) {
            mBtnClose.restart(closeTime);
        }
    }

    public void cancelCloseTime() {
        if (mBtnClose != null) {
            mBtnClose.destory();
        }
    }

    public void showLoadingArea() {
        if (mLlLoading != null) {
            mLlLoading.setVisibility(View.VISIBLE);
        }
    }

    public void hideLoadingArea() {
        if (mLlLoading != null) {
            mLlLoading.setVisibility(View.GONE);
        }
    }

    //    @Override
    //    protected boolean isSupportAutoQuit() {
    //        return true;
    //    }
    //
    //    @Override
    //    protected long getQuitTimeMillis() {
    //        return 1000 * 120;
    //    }
}
